#include "custom.h"
#include "helpers.h"
#include "stdlib.h"
#include "typechk.h"

/***** STATE VARIABLES ******/
StateVariable deviceVariables[NUMOFVARS] = {
	"InternetGatewayDevice.LANDeviceNumberOfEntries", testget, NULL, 0,
	"InternetGatewayDevice.WANDeviceNumberOfEntries", testget, NULL, 0,
	"InternetGatewayDevice.DeviceInfo.Manufactorer", testget, NULL, 0,
	"InternetGatewayDevice.DeviceInfo.ManufactorerOUI", testget, NULL, 0,
	"InternetGatewayDevice.DeviceInfo.ModelName", testget, NULL, 0,
	"InternetGatewayDevice.DeviceInfo.Description", testget, NULL, 0,
	"InternetGatewayDevice.DeviceInfo.ProductClass", testget, NULL, 0,
	"InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService", testget, testset, 1,
	"InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries", testget, NULL, 0,
	"InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable", testget, testset, 1,
	"InternetGatewayDevice.Layer3Forwarding.Forwarding.Status", testget, testset, 1,
	"InternetGatewayDevice.Layer3Forwarding.Forwarding.Type", testget, testset, 1,
	"InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric", testget, testset, 1,
	"InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU", testget, testset, 1,
	"InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_Variable", testget, NULL, 0,
	"InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable", testget, testset, 1,
	"InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_Conditional", testget, NULL, 0,
	"InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_NotConditional", testget, NULL, 0,
	"InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_CondObj.X_NTUA_GR_cond", testget, NULL, 0,
	"InternetGatewayDevice.ManagementServer.URL", testget, testset, 1,
	"InternetGatewayDevice.ManagementServer.ConnectionRequestURL", testget, NULL, 0,
 	"InternetGatewayDevice.ManagementServer.PeriodicInformInterval", testget, testget, 1,
	"InternetGatewayDevice.ManagementServer.PeriodicInformEnable", testget, testget, 1,

};

/***** STATIC VARIABLES ******/
/* These are used with stand alone state varriables */
//static char *__ACSconnectionURL="http://127.0.0.1:801";
static char *__CPEconnectionString="http://172.16.8.143:24582/CONNECT";
//static char *__ACSconnectionURL="http://iop.tw.workssys.com/comserver/node1/tr069";
//static char *__ACSconnectionURL="http://172.16.8.180:9000";
//static char *__ACSconnectionURL="http://172.16.8.143:33333";
static char *__ACSconnectionURL="http://172.16.8.143:8080:/openacs/acs/";

/***** SET FUNCTIONS *****/
void testset(ParameterValueList *params) {
	unsigned int i;
	//TODO: Add initialization code for this function here...

	for(i=0;i<params->size;i++){
		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService")==0) {
			char *value = params->parameters[i].value;
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService me timh %s", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable")==0) {
			int value = parseBoolean(params->parameters[i].value);
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable me timh %d", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Status")==0) {
			char *value = params->parameters[i].value;
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Status me timh %s", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.Forwarding.Status" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Type")==0) {
			char *value = params->parameters[i].value;
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Type me timh %s", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.Forwarding.Type" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric")==0) {
			long int value = parseInt(params->parameters[i].value);
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric me timh %d", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU")==0) {
			unsigned long int value = parseUnsignedInt(params->parameters[i].value);
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU me timh %u", value);
			//TODO: add code here so that "InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable")==0) {
			char *value = params->parameters[i].value;
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable me timh %s", value);
			//TODO: add code here so that "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable" = value

		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.ManagementServer.URL")==0) {
			char *value = params->parameters[i].value;
			PRINTD("Klh9hke h set gia thn InternetGatewayDevice.ManagementServer.URL me timh %s", value);
			__ACSconnectionURL = strdup(value);
		}

	}
	//return 0;
}


/***** GET FUNCTIONS *****/
void testget(ParameterValueList *params) {
	unsigned int i;
	//TODO: Add initialization code for this function here...

	for(i=0;i<params->size;i++){
		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.LANDeviceNumberOfEntries")==0) {
			unsigned long int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.LANDeviceNumberOfEntries");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.LANDeviceNumberOfEntries"

			char __a[20];
			sprintf(__a,"%lu",value);
			params->parameters[i].value = strdup(__a);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.WANDeviceNumberOfEntries")==0) {
			unsigned long int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.WANDeviceNumberOfEntries");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.WANDeviceNumberOfEntries"

			char __a[20];
			sprintf(__a,"%lu",value);
			params->parameters[i].value = strdup(__a);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.DeviceInfo.Manufactorer")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.DeviceInfo.Manufactorer");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.DeviceInfo.Manufactorer"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.DeviceInfo.ManufactorerOUI")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.DeviceInfo.ManufactorerOUI");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.DeviceInfo.ManufactorerOUI"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.DeviceInfo.ModelName")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.DeviceInfo.ModelName");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.DeviceInfo.ModelName"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.DeviceInfo.Description")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.DeviceInfo.Description");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.DeviceInfo.Description"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.DeviceInfo.ProductClass")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.DeviceInfo.ProductClass");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.DeviceInfo.ProductClass"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries")==0) {
			unsigned long int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.ForwardNumberOfEntries"

			char __a[20];
			sprintf(__a,"%lu",value);
			params->parameters[i].value = strdup(__a);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable")==0) {
			int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable". This is a boolean variable, so only values 0 or 1 are allowed.

			params->parameters[i].value = strdup(value?"1":"0");
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Status")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Status");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.Forwarding.Status"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Type")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.Type");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.Forwarding.Type"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric")==0) {
			long int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric"

			char __a[20];
			sprintf(__a,"%ld",value);
			params->parameters[i].value = strdup(__a);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU")==0) {
			unsigned long int value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU");
			value=0;
			//TODO: add code here so that value = "InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU"

			char __a[20];
			sprintf(__a,"%lu",value);
			params->parameters[i].value = strdup(__a);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_Variable")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_Variable");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_Variable"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable");
			//This parameter is not readable, so an empty string must be returned.
			params->parameters[i].value = strdup("");
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_Conditional")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_Conditional");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_Conditional"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_NotConditional")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_NotConditional");
			value="";
			//TODO: add code here so that value = "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_NotConditional"

			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_CondObj.X_NTUA_GR_cond")==0) {
			DateTime value={2005,1,1,1,1,1};
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_CondObj.X_NTUA_GR_cond");
			//TODO: add code here so that value = "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_NotRequired.X_NTUA_GR_CondObj.X_NTUA_GR_cond"

			params->parameters[i].value = strdup(datetoasci(&value));
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.ManagementServer.URL")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.ManagementServer.URL");
			value = __ACSconnectionURL;
			params->parameters[i].value = strdup(value);
		}

		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.ManagementServer.ConnectionRequestURL")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.ManagementServer.ConnectionRequestURL");
			value = __CPEconnectionString;
			params->parameters[i].value = strdup(value);
		}
		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.ManagementServer.PeriodicInformInterval")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.ManagementServer.PeriodicInformInterval");
			value = __CPEconnectionString;
			params->parameters[i].value = strdup(value);
		}
		if(strcmp(params->parameters[i].name, "InternetGatewayDevice.ManagementServer.PeriodicInformEnable")==0) {
			char *value;
			PRINTD("Klh9hke h get gia thn InternetGatewayDevice.ManagementServer.PeriodicInformEnable");
			value = __CPEconnectionString;
			params->parameters[i].value = strdup(value);
		}



	}
	//return 0;
}


/***** OTHERS *****/
DeviceIdStruct *getDeviceId(void) {
	DeviceIdStruct *deviceId = (DeviceIdStruct *)malloc(sizeof(DeviceIdStruct) ); 
	deviceId->manufactorer = "Serafeim";
	deviceId->OUI = "123456";
	deviceId->productClass = "Testing";
	deviceId->serialNumber = "12312131";
	return deviceId;
}

ParameterValueList *getInformParameterList(void) {
	ParameterValueList *parameterList = newParameterValueList(2);
	parameterList->parameters[0].name = strdup("InternetGatewayDevice.ManagementServer.URL");
	parameterList->parameters[0].value = strdup( "https://127.0.0.1:80");
	parameterList->parameters[1].name = strdup("InternetGatewayDevice.ManagementServer.ConnectionRequestURL");
	parameterList->parameters[1].value = strdup( "http://127.0.0.1:24582/CONNECT");
	return parameterList;
}

int getConnectionAddress(char *__addr, int *__port, int *__secure) {
	char *__acsAddress = __ACSconnectionURL;
	char *__tmpbuf;
	int __p1, __p2;
if(strstr(__acsAddress, "https://") == NULL) *__secure = 0;
else *__secure = 1;
	__tmpbuf = strstr(__acsAddress,"//");
	if(__tmpbuf == NULL) __p1 = 0;
	else __p1 = __tmpbuf - __acsAddress + 2;
	__tmpbuf = strstr(__acsAddress+__p1, ":");
	if(__tmpbuf == NULL) {
		*__port = 80;
		__p2 = strlen(__acsAddress);
	} else {
		__p2 = __tmpbuf - __acsAddress;
		*__port = atoi(__acsAddress+__p2+1);
	}
	strncpy(__addr, __acsAddress+__p1, __p2-__p1);
	*((__addr)+__p2-__p1) = 0;

	return 0;
}

char *getConnectionString() {
	return __CPEconnectionString;
}

unsigned int getListeningPort() {
	return 3257;
}

int checkParameter(ParameterValueStruct pv) {
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.DefaultConnectionService")==0) {
		return (checkString(pv.value, 256));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Enable")==0) {
		return (checkBoolean(pv.value));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Status")==0) {
		if (pv.value==NULL) return -INVALID_PARAMETER_TYPE;
		if(strcmp(pv.value, "Enabled")==0) return 0;
		if(strcmp(pv.value, "Disabled")==0) return 0;
		if(strcmp(pv.value, "Error")==0) return 0;
		return -INVALID_PARAMETER_VALUE;
	}
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.Type")==0) {
		if (pv.value==NULL) return -INVALID_PARAMETER_TYPE;
		if(strcmp(pv.value, "Default")==0) return 0;
		if(strcmp(pv.value, "Network")==0) return 0;
		if(strcmp(pv.value, "Host")==0) return 0;
		return -INVALID_PARAMETER_VALUE;
	}
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.ForwardMetric")==0) {
		int __val; 
		if(checkInt(pv.value)==0) __val = parseInt(pv.value) ;
		else return -INVALID_PARAMETER_TYPE; 
		if(__val <-1) return -INVALID_PARAMETER_VALUE;
		return 0;
	}
	if(strcmp(pv.name, "InternetGatewayDevice.Layer3Forwarding.Forwarding.MTU")==0) {
		return (checkUnsignedInt(pv.value));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.X_NTUA_GR_TestObject.X_NTUA_GR_WritableVariable")==0) {
		return (checkString(pv.value, 8));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.ManagementServer.URL")==0) {
		return (checkString(pv.value, 256));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.ManagementServer.PeriodicInformInterval")==0) {
		return (checkString(pv.value, 256));
	}
	if(strcmp(pv.name, "InternetGatewayDevice.ManagementServer.PeriodicInformEnable")==0) {
		return (checkString(pv.value, 256));
	}

	return -INVALID_PARAMETER_NAME;
}

void handleReboot(void) {
	// TODO: Add code that reboots the CPE
}

void handleUpload(char *commandKey, char *fileType, char* URL, char *username, char *password, unsigned int delaySeconds, short int *status, DateTime **startTime, DateTime **completeTime) {
	// TODO: Add code here that handles the Upload method.
	// The first 6 parameters are IN while the 
	// The last 3 parameters are OUT
	// *StartTime and *CompleteTime can be NULL while *status can be 0 or 1
	*status = 0;
	*startTime = NULL;
	*completeTime = NULL;
}

void handleDownload(char *commandKey, char *fileType, char* URL, char *username, char *password, unsigned int fileSize, char *targetFileName, unsigned int delaySeconds, char *successURL, char *failureURL, short int *status, DateTime **startTime, DateTime **completeTime) {
	// TODO: Add code here that handles the Download method.
	// The first 9 parameters are IN while the 
	// The last 3 parameters are OUT
	// *StartTime and *CompleteTime can be NULL while *status can be 0 or 1
	*status = 0;
	*startTime = NULL;
	*completeTime = NULL;
}
